package at.fhj.mobsecdev.cookit.activities;

import java.util.ArrayList;
import java.util.List;

import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.ActionBar.TabListener;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.FragmentTransaction;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import at.fhj.mobsecdev.cookit.R;
import at.fhj.mobsecdev.cookit.adapter.RecipeAdapter;
import at.fhj.mobsecdev.cookit.model.Recipe;
import at.fhj.mobsecdev.cookit.util.Constants;
import at.fhj.mobsecdev.cookit.webrequests.ViewRecipesAsyncWebCall;
import at.fhj.mobsecdev.cookit.webrequests.ViewRecipesAsyncWebCall.AddRecipes;
import at.fhj.mobsecdev.cookit.webrequests.WebServiceUrls;

/**
 * Main activity, that shows tabs, list of recipes and furhter selections like Login.
 *
 */
public class MainActivity extends Activity implements TabListener, OnItemClickListener, AddRecipes, OnScrollListener, OnClickListener {

	private ListView recipeListView;
	
	/* Recipes are seperated on multiple pages, starting from 0, to implement lazy
	 * loading. CurrentPage is therefore forwaded to the WS-call and incremented after
	 * every call 
	 */
	private int currentPage = 0;
	
	private Menu mainMenu;
	private EditText searchInput;
	
	private SharedPreferences credentialsSharedPreferences;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		credentialsSharedPreferences = getSharedPreferences(Constants.SHARED_PREFERNECES_CREDENTIALS, Context.MODE_PRIVATE);
		
		recipeListView = (ListView)findViewById(R.id.recipe_list);
		
		/* Add Tabs */
		ActionBar actionBar = getActionBar();
		actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
		
		Tab newestRecipeTab = actionBar.newTab();
		newestRecipeTab.setText(R.string.newest_recipes_tab);
		newestRecipeTab.setTabListener(this);
		actionBar.addTab(newestRecipeTab);
		
		/* Add My Recipes tab only if user is logged in */
		if(!credentialsSharedPreferences.getString(Constants.PREFERENCE_USERNAME, "username").equals("username") &&
				!credentialsSharedPreferences.getString(Constants.PREFERENCE_PASSWORDHASH, "passwordhash").equals("passwordhash")) {
			Tab myRecipeTab = actionBar.newTab();
			myRecipeTab.setText(R.string.my_recipes_tab);
			myRecipeTab.setTabListener(this);
			actionBar.addTab(myRecipeTab);
		}
		
		/* Add recipe list */
		List<Recipe> recipeList = new ArrayList<Recipe>();
		final RecipeAdapter adapter = new RecipeAdapter(this, R.layout.recipe_list_element, recipeList);
		recipeListView.setAdapter(adapter);
		recipeListView.setOnItemClickListener(this);
		recipeListView.setOnScrollListener(this);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		mainMenu = menu;
		getMenuInflater().inflate(R.menu.main, mainMenu);
		
		/* If user is logged in, show logout button in action bar */
		if(credentialsSharedPreferences.getString(Constants.PREFERENCE_USERNAME, "username") != "username" &&
				credentialsSharedPreferences.getString(Constants.PREFERENCE_PASSWORDHASH, "passwordhash") != "passwordHash") {
			mainMenu.findItem(R.id.login).setVisible(false);
			mainMenu.findItem(R.id.logout).setVisible(true);
		}
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		/* Action Bar Handling */
		int id = item.getItemId();
		
		/* Show Recipe of the Day */
		if (id == R.id.recipe_of_the_day) {
			Intent intent = new Intent(this, ViewRecipeActivity.class);
			intent.putExtra(Constants.DISPLAY_ROTD, true);
			startActivity(intent);
			
		/* Show Add recipe form */
		} else if (id == R.id.add_recipe) {
			Intent intent = new Intent(this, ViewAddRecipeActivity.class);
			startActivity(intent);
		}
		/* Show search recipe popup */
		else if( id == R.id.search_recipe) {
			AlertDialog.Builder alert = new AlertDialog.Builder(this);

			alert.setTitle(getResources().getString(R.string.search_recipe));
			alert.setMessage(getResources().getString(R.string.search_recipe_instruction));

			// Set an EditText view to get user input 
			searchInput  = new EditText(this);
			alert.setView(searchInput);

			alert.setPositiveButton(this.getResources().getString(R.string.ok), this);
			
			alert.show();
		}
		/* Log user out */
		else if ( id == R.id.logout)
		{
			credentialsSharedPreferences.edit()
				.clear()	
				.commit();
			mainMenu.findItem(R.id.login).setVisible(true);
			mainMenu.findItem(R.id.logout).setVisible(false);
			getActionBar().removeTabAt(1);
		}
		/* Log user in */
		else if ( id == R.id.login)
		{
			Intent intent = new Intent(this, LoginActivity.class);
			startActivity(intent);
		}
		
		return super.onOptionsItemSelected(item);
	}

	@Override
	public void onTabReselected(Tab tab, FragmentTransaction ft) { return; }

	@Override
	public void onTabSelected(Tab tab, FragmentTransaction ft) {
		/* Reset search string & page value */
		currentPage = 0;
		searchInput = null;
		
		/* User selects Newest Recipes tab */
		if(tab.getText().equals(getResources().getString(R.string.newest_recipes_tab)))
		{
			new ViewRecipesAsyncWebCall(this, MainActivity.this).execute(String.format(WebServiceUrls.VIEW_BY_DATE_URL, currentPage));
		}
		/* User selects My Recipes tab */
		else if(tab.getText().equals(getResources().getString(R.string.my_recipes_tab)))
		{
			new ViewRecipesAsyncWebCall(this, MainActivity.this).execute(String.format(WebServiceUrls.VIEW_BY_OWNER_URL, 
					credentialsSharedPreferences.getString(Constants.PREFERENCE_USERNAME, ""), currentPage));
		}
	}

	@Override
	public void onTabUnselected(Tab tab, FragmentTransaction ft) {
		/* Remove all items from ListView when tab selection changes */
		RecipeAdapter adapter = (RecipeAdapter)recipeListView.getAdapter();
		adapter.clear();
	}

	/* ListView Events */
	
	/**
	 * Is called, if user selects a recipe in the list, forward to recipe view activity
	 */
	@Override
	public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
		Intent intent = new Intent(this, ViewRecipeActivity.class);
		
		Recipe recipe = (Recipe)recipeListView.getItemAtPosition(position);
		intent.putExtra(Constants.DISPLAY_SELECTED_RECIPE, recipe);
		startActivity(intent);
	}
	

	private int preLast; //helper variable to avoid multiple calls for last item
	@Override
	public void onScroll(AbsListView lw, final int firstVisibleItem,
	                 final int visibleItemCount, final int totalItemCount) {
		    // Calculation to determine if the last item is fully visible.
		     final int lastItem = firstVisibleItem + visibleItemCount;
		   if(lastItem == totalItemCount) {
		      if(preLast!=lastItem && currentPage != 0){ 
		        Log.d("ListView", "Last element reached, load next page");
		        preLast = lastItem;
		        
		        ActionBar actionBar = getActionBar();
		        /* If recipes shown are search results */
		        if(searchInput != null)
		        {
		    		new ViewRecipesAsyncWebCall(this, MainActivity.this).execute(String.format(WebServiceUrls.SEARCH_BY_NAME, 
		    				searchInput.getText().toString(), currentPage++));
		    		return;
		        }
		        /* If recipes shown are newest recipes */
		        if(actionBar.getSelectedTab().getText().equals(getResources().getString(R.string.newest_recipes_tab)))
				{
					new ViewRecipesAsyncWebCall(this, MainActivity.this).execute(String.format(WebServiceUrls.VIEW_BY_DATE_URL, currentPage++));
				}
		        /* If recipes shown are users own recipes */
				else if(actionBar.getSelectedTab().getText().equals(getResources().getString(R.string.my_recipes_tab)))
				{
					new ViewRecipesAsyncWebCall(this, MainActivity.this).execute(String.format(WebServiceUrls.VIEW_BY_OWNER_URL, 
							credentialsSharedPreferences.getString(Constants.PREFERENCE_USERNAME, ""), currentPage++));
				}
		      }
		   }
	}
	
	@Override
	public void onScrollStateChanged(AbsListView view, int scrollState) { }
	
	/* Events of ViewRecipeAsyncWebCall */
	
	/**
	 * Adds result of Web Service call to recipe list
	 */
	@Override
	public void addRecipes(List<Recipe> newRecipes)
	{
		/* If web service returns nothing, just return and don't reset prelast, so that web service is not called again */
		if(newRecipes.size() == 0) {
			return;
		}
		
		RecipeAdapter adapter = (RecipeAdapter)recipeListView.getAdapter();
		adapter.addRecipes(newRecipes);
		
		//for every call use notifyDataSetChanged() to prevent listview from scrolling back up to top
		adapter.notifyDataSetChanged();
		preLast = 0; //reset detection if scrolling of list is at bottom
		currentPage++;
		
		/* Don't call WS again if the total of recipes found is less than the number of recipes per page */
		if(newRecipes.size() != WebServiceUrls.RECIPES_PER_PAGE) {
			preLast += newRecipes.size();
		}
	}

	@Override
	public void webServiceCallFailed(Exception e) {
		Toast.makeText(this, e.getMessage() , Toast.LENGTH_LONG).show();
	}

	/* Callback for Search function */
	
	@Override
	public void onClick(DialogInterface dialog, int which) {
		if(searchInput.getText().toString() == null || searchInput.getText().toString().trim().equals("")) {
			return;
		}
		
		/* Reset page counter, as this is a new recipe list */
		currentPage = 0;
		
		/* Remove currently shown recipes */
		RecipeAdapter adapter = (RecipeAdapter)recipeListView.getAdapter();
		adapter.clear();
		
		new ViewRecipesAsyncWebCall(this, MainActivity.this).execute(String.format(WebServiceUrls.SEARCH_BY_NAME, 
				searchInput.getText().toString(), currentPage));
	}
}
